<?php
// +----------------------------------------------------------------------
// | sfadmin - Suifeng Administration
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2020 http://suifeng.tech All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: suifeng <1787585212@qq.com>
// +----------------------------------------------------------------------

namespace suifeng\builder;

use suifeng\builder\Pagination;
use suifeng\builder\table\column\Column;
use suifeng\builder\table\action\Action;
use suifeng\builder\table\button\Button;
use suifeng\helper\BaseObject;

class ListBuilder extends BaseObject
{
    /**
     * 数据列。
     *
     * @var array
     */
    public $columns = array();

    /**
     * 数据行任务。
     *
     * @var array
     */
    public $actions = array();

    /**
     * 全局操作按钮。
     *
     * @var array
     */
    public $buttons = array();

    /**
     * 控制器实例。
     *
     * @var unknown
     */
    public $controller;

    /**
     * 模型对象。
     *
     * @var unknown
     */
    public $model_object;

    /**
     * 主键盘字段，默认为id。
     *
     * @var unknown
     */
    public $key_field;

    /**
     * 数据列表。
     *
     * @var array
     */
    public $data_list = array();

    /**
     * 记录总行数。
     *
     * @var unknown
     */
    public $rows_count = 0;

    /**
     * 每页显示行数。
     *
     * @var unknown
     */
    public $page_size;

    /**
     * 每页显示页数。
     *
     * @var unknown
     */
    public $page_number;

    /**
     * 分页URL地址，页数用[page]代替。
     *
     * @var unknown
     */
    public $page_url;

    /**
     * 排序字段。
     *
     * @var unknown
     */
    public $sort_field;

    /**
     * 排序顺序。
     *
     * @var string
     */
    public $sort_order;

    /**
     * 搜索关键字。
     *
     * @var string
     */
    public $search_word;

    /**
     * 筛选列表。
     *
     * @var string
     */
    public $filter_params = array();

//     /**
//      * 是否启用行选择？
//      *
//      * @var boolean
//      */
//     public $enable_select = false;

    /**
     * 是否启用行选择？
     *
     * @var boolean
     */
    public $enable_search = false;

    /**
     * 是否启用筛选？
     *
     * @var boolean
     */
    public $enable_filter = false;

    /**
     * 是否启用排序？
     *
     * @var boolean
     */
    public $enable_sort = false;

    /**
     * 是否启用分页？
     *
     * @var boolean
     */
    public $enable_page = true;

    /**
     * 可排序字段。
     *
     * @var array
     */
    public $avail_sort_fields = array();

    /**
     * 可筛选字段。
     *
     * @var array
     */
    public $avail_filter_fields = array();

    /**
     * 可搜索字段。
     *
     * @var array
     */
    public $avail_search_fields = array();

    /**
     * 附加的查询条件。
     *
     * @var array
     */
    public $extra_wheres = array();

    /**
     * 默认排序字段。
     *
     * @var unknown
     */
    public $default_sort_field;

    /**
     * 默认排序顺序。
     *
     * @var unknown
     */
    public $default_sort_order;

    /**
     * 默认分页大小。
     *
     * @var unknown
     */
    public $default_page_size;

    /**
     * 头部内容。
     *
     * @var array
     */
    public $top_content = array();

    /**
     * 底部内容。
     *
     * @var array
     */
    public $bottom_content = array();

    /**
     * 构造方法。
     */
    public function __construct() {}

    /**
     * 添加显示列。
     */
    public function add_column($name, $type = null, $title = null, $config = [])
    {
        if (empty($type)) {
            $class = '\\suifeng\\builder\\table\\column\\' . implode('', array_map('ucfirst', explode('_', $name)));
            if (!class_exists($class)) {
                $class = '\\suifeng\\builder\\table\\column\\text';
            }
        } else {
            $class = '\\suifeng\\builder\\table\\column\\' . implode('', array_map('ucfirst', explode('_', $type)));
        }

        if (!class_exists($class)) {
            throw new \Exception('Column type not exists: ' . $type);
        }

        $config['name'] = $name;
        $config['table'] = $this;

        if (is_array($title)) {
            $config = array_merge($config, $title);
        } else {
            $title && $config['title'] = $title;
        }

        $column = new $class($config);
        $this->columns[$name] = $column;
        return $column;
    }

    /**
     * 添加行操作。
     */
    public function add_action($name, $type = null, $title = null, $config = [])
    {
        if (empty($type)) {
            $class = '\\suifeng\\builder\\table\\action\\' . implode('', array_map('ucfirst', explode('_', $name)));
            if (!class_exists($class)) {
                $class = '\\suifeng\\builder\\table\\action\\action';
            }
        } else {
            $class = '\\suifeng\\builder\\table\\action\\' . implode('', array_map('ucfirst', explode('_', $type)));
        }

        if (!class_exists($class)) {
            throw new \Exception('Action type not exists: ' . $type);
        }

        $config['name'] = $name;
        $config['table'] = $this;

        if (is_array($title)) {
            $config = array_merge($config, $title);
        } else {
            $title && $config['title'] = $title;
        }

        $action = new $class($config);
        $this->actions[$name] = $action;
        return $action;
    }

    /**
     * 添加操作按钮。
     */
    public function add_button($name, $type = null, $title = null, $config = [])
    {
        if (empty($type)) {
            $class = '\\suifeng\\builder\\table\\button\\' . implode('', array_map('ucfirst', explode('_', $name)));
            if (!class_exists($class)) {
                $class = '\\suifeng\\builder\\table\\button\\button';
            }
        } else {
            $class = '\\suifeng\\builder\\table\\button\\' . implode('', array_map('ucfirst', explode('_', $type)));
        }

        if (!class_exists($class)) {
            throw new \Exception('Button type not exists: ' . $type);
        }

        $config['name'] = $name;
        $config['table'] = $this;

        if (is_array($title)) {
            $config = array_merge($config, $title);
        } else {
            $title && $config['title'] = $title;
        }

        $button = new $class($config);
        $this->buttons[$name] = $button;
        return $button;
    }

//     /**
//      * 初始化显示列。
//      *
//      * @param unknown $config
//      */
//     protected function _init_columns($config)
//     {
//         foreach ($config as $column) {
//             $column['table'] = $this;
//             $instance = Column::create($column);
//             $this->columns[] = $instance;
//         }
//     }

//     /**
//      * 初始化行操作。
//      *
//      * @param unknown $config
//      */
//     protected function _init_actions($config)
//     {
//         foreach ($config as $action) {
//             $action['table'] = $this;
//             $instance = Action::create($action);
//             $this->actions[] = $instance;
//         }
//     }

//     /**
//      * 初始化操作按钮。
//      *
//      * @param unknown $config
//      */
//     protected function _init_buttons($config)
//     {
//         foreach ($config as $button) {
//             $button['table'] = $this;
//             $instance = Button::create($button);
//             $this->buttons[] = $instance;
//         }
//     }

//     /**
//      * 根据模型解析显示栏位。
//      *
//      * @return unknown[]
//      */
//     protected function _parse_columns_from_model()
//     {
//         $model_fields = $this->model->model_fields;
//         $list_fields = $this->model->list_fields;

//         // 默认是所有字段
//         if (! $list_fields) {
//             $list_fields = array_keys($model_fields);
//         }

//         $result_list = array();

//         foreach ($list_fields as $key => $val) {
//             if (is_numeric($key)) {
//                 if (is_array($val)) {
//                     $column_config = $val;
//                     $field_name = isset($column_config['field']) ? $column_config['field'] : null;
//                 } else {
//                     $field_name = $val;
//                     $column_config = array();
//                 }
//             } else {
//                 $field_name = $key;
//                 $column_config = $val;
//             }

//             // 无效字段
//             if (! array_key_exists($field_name, $model_fields)) {
//                 continue;
//             }

//             // 字段名称
//             $column_config['field'] = $field_name;

//             // 合并字段定义
//             if (isset($model_fields[$field_name]['column']) &&
//                 is_array($model_fields[$field_name]['column'])) {
//                 $column_config = array_merge($model_fields[$field_name]['column'], $column_config);
//             }

//             // 显示类型
//             if (! isset($column_config['column'])) {
//                 if (isset($model_fields[$field_name]['column']) && is_string($model_fields[$field_name]['column'])) {
//                     $column_config['column'] = $model_fields[$field_name]['column'];
//                 } else {
//                     $column_config['column'] = 'text';
//                 }
//             }

//             // 显示标题
//             if (! isset($column_config['title'])) {
//                 if (isset($model_fields[$field_name]['title'])) {
//                     $column_config['title'] = $model_fields[$field_name]['title'];
//                 } else {
//                     $column_config['title'] = StrUtil::friendly_text($field_name);
//                 }
//             }

//             // 数据类型
//             $column_config['data_type'] = $model_fields[$field_name]['dbtype'];

//             $result_list[] = $column_config;
//         }

//         return $result_list;
//     }

//     /**
//      * 从模型中解析行操作。
//      *
//      * @return unknown[]
//      */
//     protected function _parse_actions_from_model()
//     {
//         $list_actions = $this->model->list_actions;

//         $result_list = array();

//         foreach ($list_actions as $key => $val) {
//             if (is_numeric($key)) {
//                 if (is_array($val)) {
//                     $action_config = $val;
//                     $action_type = isset($action_config['action']) ? $action_config['action'] : null;
//                 } else {
//                     $action_type = $val;
//                     $action_config = array();
//                 }
//             } else {
//                 $action_type = $key;
//                 $action_config = $val;
//             }

//             // 无效
//             if (! $action_type) {
//                 continue;
//             }

//             $action_config['action'] = $action_type;
//             $result_list[] = $action_config;
//         }

//         return $result_list;
//     }

//     /**
//      * 从模型中解析按钮。
//      *
//      * @return unknown[]
//      */
//     protected function _parse_buttons_from_model()
//     {
//         $list_buttons = $this->model->list_buttons;

//         $result_list = array();

//         foreach ($list_buttons as $key => $val) {
//             if (is_numeric($key)) {
//                 if (is_array($val)) {
//                     $button_config = $val;
//                     $button_type = isset($button_config['button']) ? $button_config['button'] : null;
//                 } else {
//                     $button_type = $val;
//                     $button_config = array();
//                 }
//             } else {
//                 $button_type = $key;
//                 $button_config = $val;
//             }

//             // 无效
//             if (! $button_type) {
//                 continue;
//             }

//             $button_config['button'] = $button_type;
//             $result_list[] = $button_config;
//         }

//         return $result_list;
//     }


    /**
     * 输出HTML。
     *
     * @return string
     */
    public function render_html()
    {
        $this->_initialize();

//         if ($this->enable_select) {
//             $selected_column = Column::create('selected');
//             $selected_column->table =& $this;
//             $selected_column->field = $this->key_field;
//             $selected_column->name = 'selected';
//             $this->columns = array_merge(array($selected_column->name => $selected_column), $this->columns);
//         }

//         if ($this->actions) {
//             $actions_column = Column::create('actions');
//             $actions_column->table =& $this;
//             $actions_column->field = $this->key_field;
//             $actions_column->name = 'actions';
//             $this->columns[$actions_column->name] = $actions_column;
//         }

        if ($this->rows_count > $this->page_size) {
            $pagination = new Pagination();
            $pagination->pageVar = 's_page';
            $pagination->totalRows = $this->rows_count;
            $pagination->listRows = $this->page_size;
            $pagination->nowPage = $this->page_number;
            $pagination->url = $this->page_url;
        }

        ob_start();
        include dirname(__FILE__) . '/table/Table.tpl';
        $output = ob_get_contents();
        ob_end_clean();

        return $output;
    }

    protected function _initialize()
    {
        if (isset($this->_initialized) && $this->_initialized) {
            return;
        }

        $input = request()->param();

        if ($this->enable_page) {
            if (isset($input['s_size'])) {
                $this->page_size = intval($input['s_size']);
            } else {
                if (!$this->page_size) {
                    $this->page_size = $this->default_page_size ?: config('ADMIN_PAGE_ROWS');
                }
            }

            if (isset($input['s_page'])) {
                $this->page_number = intval($input['s_page']);
            } else {
                if (!$this->page_number) {
                    $this->page_number = 1;
                }
            }

            if (!$this->page_url) {
                $params = array();

                foreach (request()->param() as $key => $value) {
                    if (substr($key, 0, 2) == 'f_' || substr($key, 0, 2) == 's_') {
                        $params[$key] = $value;
                    }
                }

                $this->page_url = url(null, $params);
            }
        }

        if ($this->enable_sort) {
            if (isset($input['s_sort'])) {
                $this->sort_field = intval($input['s_sort']);
            } else {
                if (!$this->sort_field) {
                    $this->sort_field = $this->default_sort_field ?: null;
                }
            }

            if (isset($input['s_order'])) {
                $this->sort_order = intval($input['s_order']);
            } else {
                if (!$this->sort_order) {
                    $this->sort_order = $this->default_sort_order ?: null;
                }
            }

            if (!$this->sort_field) {
                $this->sort_field = $this->_find_default_sort_filed();
            }

            if ($this->sort_field) {
                if (!$this->sort_order) {
                    $this->sort_order = 'asc';
                }
            } else {
                $this->sort_order = null;
            }
        }

        if ($this->enable_search) {
            if (isset($input['s_word'])) {
                $this->search_word = $input['s_word'];
            } else {
                if (!$this->search_word) {
                    $this->search_word = '';
                }
            }
        }

        if ($this->enable_filter && empty($this->filter_params)) {
            $this->filter_params = array();
            foreach ($input as $key => $value) {
                if (substr($key, 0, 2) == 'f_') {
                    $this->filter_params[substr($key, 2)] = $value;
                }
            }
        }

        $this->_initialized = true;
    }

    protected function _find_default_sort_filed()
    {
        foreach ($this->columns as $column) {
            if (!empty($column->field)) {
                return $column->field;
            }
        }
        return null;
    }

    public function get_where_map()
    {
        $this->_initialize();

        $where_map = (array) $this->extra_wheres;

        if ($this->enable_search && $this->search_word && $this->avail_search_fields) {
            $condition = array('like', '%' . $this->search_word . '%');
            $where_map[implode('|', $this->avail_search_fields)] = $condition;
        }

        foreach ($this->filter_params as $field => $value) {
            $condition = array('like', '%' . $this->value . '%');
            $where_map[$field] = $condition;
        }

        return $where_map;
    }

//     /**
//      * 加载模型数据。
//      *
//      * @param unknown $params
//      */
//     protected function _load_model_data($params)
//     {
//         $model_fields = $this->model->model_fields;

//         $where_map = $this->_build_where_map($params);

//         $rows_count = $this->model->where($where_map)
//             ->count();

//         $query = $this->model->where($where_map);
//         $query->page($params['page_num'], $params['page_size']);

//         if ($params['sort_field'] && $params['sort_order']) {
//             $query->order($params['sort_field'] . ' ' . $params['sort_order']);
//         }

//         $data_list = $query->select();

//         return array($rows_count, $data_list);
//     }

//     /**
//      * 依据请求参数，建立查询条件。
//      *
//      * @param unknown $params
//      * @return array|string[]
//      */
//     protected function _build_where_map($params)
//     {
//         $where_map = $this->extra_wheres;

//         // 关键字搜索
//         if ($params['keyword'] && $this->search_fields) {
//             $condition = array('like', '%' . $params['keyword'] . '%');
//             $where_map[implode('|', $this->search_fields)] = $condition;
//         }

//         return $where_map;
//     }

//     /**
//      * 获取请求参数。
//      *
//      * @return mixed
//      */
//     protected function _fetch_request_params()
//     {
//         $params['keyword'] = input('keyword', '');
//         $params['page_num'] = input(config('paginate.var_page'), 1, 'intval');
//         $params['page_size'] = input('size', $this->page_size, 'intval');
//         $params['sort_field'] = input('sort', $this->sort_field);
//         $params['sort_order'] = input('order', $this->sort_order);
//         return $params;
//     }

//     public function show_table()
//     {
//         $this->_initialize();

//         $html = '<div class="row">';
//         $html .= '<div class="col-sm-12">';


//         $html .= '<table class="table table-bordered table-striped table-hover">';

//         $html .= '<thead>';
//         $html .= '<tr>';

//         foreach ($this->columns as $column) {
//             $html .= $column->render_head();
// 		}

//         $html .= '</tr>';
//         $html .= '</thead>';

//         $html .= '<tbody>';

//         if ($this->data_list) {
//             foreach ($this->data_list as $row) {
//                 $html .= '<tr>';

//                 foreach ($this->columns as $column) {
//                     $html .= $column->render_cell($row);
//                 }

//                 $html .= '</tr>';
//             }
// 		} else {
// 		    $html .= '<tr class="builder-data-empty">';
// 			$html .= '<td class="text-center empty-info" colspan="50">';
// 			$html .= '<i class="fa fa-database"></i> 暂时没有数据<br>';
// 			$html .= '</td>';
// 			$html .= '</tr>';
// 		}

//         $html .= '</tbody>';
//         $html .= '</table>';

//         $html .= '</div>';
//         $html .= '</div>';
//         return $html;
//     }

//     public function show_pagination()
//     {
//         $this->_initialize();

//         if ($this->rows_count <= $this->page_size) {
//             return;
//         }

//         $pagination = new Pagination();
//         $pagination->pageVar = 's_page';
//         $pagination->totalRows = $this->rows_count;
//         $pagination->listRows = $this->page_size;
//         $pagination->nowPage = $this->page_number;
//         $pagination->url = $this->page_url;

//         $html = '<div class="row">';
//         $html .= '<div class="col-sm-5">';
//         $html .= '<div class="pagination-info">';
//         $html .= $pagination->show_info();
//         $html .= '</div>';
//         $html .= '</div>';
//         $html .= '<div class="col-sm-7">';
//         $html .= '<div class="pagination">';
//         $html .= $pagination->show_pages();
//         $html .= '</div>';
//         $html .= '</div>';
//         $html .= '</div>';
//         return $html;
//     }

//     public function show_toolbar()
//     {
//         $this->_initialize();

//         $html = '<div class="row">';
//         $html .= '<div class="col-xs-12 col-sm-12 clearfix">';

//         $html .= '<ul class="table-fixed-toolbar">';
//         foreach ($this->buttons as $button) {
//             $html .= '<li>' . $button->render_html() . '</li>';
//         }
//         $html .= '</ul>';

//         $html .= '<ul class="pull-right table-fixed-toolbar">';

//         $html .= '<li>';
//         $html .= '<div class="btn-group">';
//         $html .= '<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">';
//         $html .= '<i class="fa fa-share"></i>导出<span class="fa fa-caret-down"></span>';
//         $html .= '</button>';
//         $html .= '<ul class="dropdown-menu pull-right">';
//         $html .= '<li><a href="#"><i class="fa fa-arrow-circle-down"></i>导出 Excel 2007</a></li>';
//         $html .= '<li><a href="#"><i class="fa fa-arrow-circle-down"></i>导出 Excel 2007</a></li>';
//         $html .= '<li><a href="#"><i class="fa fa-arrow-circle-down"></i>导出 Excel 2007</a></li>';
//         $html .= '<li><a href="#"><i class="fa fa-arrow-circle-down"></i>导出 Excel 2007</a></li>';
//         $html .= '</ul>';
//         $html .= '</div>';
//         $html .= '</li>';

//         $html .= '<li>';
//         $html .= '<div class="btn-group">';
//         $html .= '<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">';
//         $html .= '<i class="fa fa fa-list-alt"></i>显示<span class="caret"></span>';
//         $html .= '</button>';
//         $html .= '<ul class="dropdown-menu pull-right" role="menu">';
//         $html .= '<li><a href="#"><i class="fa fa-arrow-circle-down"></i>导出 Excel 2007</a></li>';
//         $html .= '<li><a href="#"><i class="fa fa-arrow-circle-down"></i>导出 Excel 2007</a></li>';
//         $html .= '<li><a href="#"><i class="fa fa-arrow-circle-down"></i>导出 Excel 2007</a></li>';
//         $html .= '<li><a href="#"><i class="fa fa-arrow-circle-down"></i>导出 Excel 2007</a></li>';
//         $html .= '</ul>';
//         $html .= '</div>';
//         $html .= '</li>';

//         $html .= '</ul>';

//         $html .= '</div>';
//         $html .= '</div>';
//         return $html;
//     }
}
